// This is to avoid code duplication, because of explicit instantiation,
// enable_if on type templates etc...
  int _cst;
  bool _sign;

public:
  static const int place = PLACE;

  constexpr Term(const Term &t) : _var(t._var), _cst(t._cst), _sign(t._sign) {}
  
  constexpr int cst() {return _cst;}
  constexpr bool sign() {return _sign;}
  constexpr int factor() const {
    return (!sign()) ? cst() : -cst();
  }
  constexpr Term operator-() {
    return (Term(_var, _cst, !_sign));
  }

  constexpr int Min(int min, int max) {
    return (!_sign) ? factor() * min : factor() * max;
  }

  constexpr int Max(int min, int max) {
    return (_sign) ? factor() * min : factor() * max;
  }

  template <typename ... T>
  constexpr int Max(std::tuple<T ...> const &mins, std::tuple<T ...> const &maxes) {
    // static_assert(std::tuple_size<T ...>::value > PLACE, 
    //               "Not enough arguments in array passed to Term::Min");
    return (_sign) ? Val(mins) : Val(maxes);
  }

  template <typename ... T>
  constexpr int Min(std::tuple<T ...> const &mins, std::tuple<T ...> const &maxes) {
    // static_assert(std::tuple_size<T ...>::value > PLACE, 
    //               "Not enough arguments in array passed to Term::Min");
    return (!_sign) ? Val(mins) : Val(maxes);
  }

  template <typename ... T>
  constexpr int Val(std::tuple<T ...> const &vals) {
    // static_assert(std::tuple_size<T ...>::value > PLACE, 
    //               "Not enough arguments in array passed to Term::Min");
    return factor() * _var(vals) ;
  }

